package org.xp.judgeplatform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.xp.judgeplatform.converter.LoginDevicesConverter;
import org.xp.judgeplatform.exception.BusinessException;
import org.xp.judgeplatform.mapper.LoginDevicesMapper;
import org.xp.judgeplatform.pojo.dto.LoginDevices.LoginDevicesRecordDTO;
import org.xp.judgeplatform.pojo.entity.LoginDevices;
import org.xp.judgeplatform.pojo.vo.LoginDevicesVO.LoginDevicesVO;
import org.xp.judgeplatform.service.LoginDevicesService;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 登录设备服务实现
 *
 */
@Slf4j
@Service
@AllArgsConstructor
public class LoginDevicesServiceImpl implements LoginDevicesService {

    private final LoginDevicesMapper loginDevicesMapper;
    private final LoginDevicesConverter loginDevicesConverter;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LoginDevicesVO recordLoginDevice(LoginDevicesRecordDTO recordDTO) {
        try {
            QueryWrapper<LoginDevices> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", recordDTO.getUserId())
                    .eq("device_id", recordDTO.getDeviceId());

            LoginDevices existingDevice = loginDevicesMapper.selectOne(queryWrapper);

            if (existingDevice != null) {
                UpdateWrapper<LoginDevices> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("id", existingDevice.getId())
                        .set("is_active", true)                              // 激活设备
                        .set("session_token", recordDTO.getSessionToken())   // 更新会话令牌
                        .set("ip_address", recordDTO.getIpAddress())         // 更新IP
                        .set("location", recordDTO.getLocation())            // 更新位置
                        .set("browser", recordDTO.getBrowser())              // 更新浏览器信息
                        .set("os", recordDTO.getOs())                        // 更新操作系统
                        .set("last_login_time", LocalDateTime.now());        // 更新最后登录时间

                loginDevicesMapper.update(null, updateWrapper);
                log.info("更新登录设备记录成功，userId: {}, deviceId: {}",
                        recordDTO.getUserId(), recordDTO.getDeviceId());

                LoginDevices updatedDevice = loginDevicesMapper.selectById(existingDevice.getId());
                return loginDevicesConverter.toVO(updatedDevice);
            } else {
                // 4. 新设备，创建记录
                LoginDevices newDevice = new LoginDevices();
                newDevice.setUserId(recordDTO.getUserId());
                newDevice.setDeviceId(recordDTO.getDeviceId());
                newDevice.setDeviceName(recordDTO.getDeviceName());
                newDevice.setDeviceType(recordDTO.getDeviceType());
                newDevice.setBrowser(recordDTO.getBrowser());
                newDevice.setOs(recordDTO.getOs());
                newDevice.setLoginMethod(recordDTO.getLoginMethod());
                newDevice.setIpAddress(recordDTO.getIpAddress());
                newDevice.setLocation(recordDTO.getLocation());
                newDevice.setIsActive(true);
                newDevice.setSessionToken(recordDTO.getSessionToken());

                loginDevicesMapper.insert(newDevice);
                log.info("创建登录设备记录成功，userId: {}, deviceId: {}",
                        recordDTO.getUserId(), recordDTO.getDeviceId());

                return loginDevicesConverter.toVO(newDevice);
            }
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            // 其他异常包装为业务异常
            log.error("记录登录设备失败，userId: {}, deviceId: {}, error: {}",
                    recordDTO.getUserId(), recordDTO.getDeviceId(), e.getMessage(), e);
            throw new BusinessException(500, "记录登录设备失败");
        }
    }

    @Override
    public org.xp.judgeplatform.common.PageResult<LoginDevicesVO> getUserDevices(Integer userId, Integer pageNum, Integer pageSize) {
        try {
            // 创建分页对象
            Page<LoginDevices> page = new Page<>(pageNum, pageSize);

            // 查询条件：按用户ID查询，按最后登录时间倒序
            QueryWrapper<LoginDevices> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId)
                    .orderByDesc("last_login_time");

            // 执行分页查询
            Page<LoginDevices> devicePage = loginDevicesMapper.selectPage(page, queryWrapper);

            // 转换为VO列表
            List<LoginDevicesVO> voList = loginDevicesConverter.toVOList(devicePage.getRecords());

            // 封装为 PageResult
            org.xp.judgeplatform.common.PageResult<LoginDevicesVO> result = 
                org.xp.judgeplatform.common.PageResult.of(voList, devicePage.getTotal(), pageNum, pageSize);

            log.info("查询用户设备列表成功，userId: {}, total: {}", userId, result.getTotal());
            return result;
        } catch (Exception e) {
            log.error("查询用户设备列表失败，userId: {}, error: {}", userId, e.getMessage(), e);
            throw new BusinessException(500, "查询设备列表失败");
        }
    }

    @Override
    public LoginDevicesVO getCurrentDevice(Integer userId, String deviceId) {
        return null;
    }

    @Override
    public void logoutDevice(Integer userId, Long deviceId) {

    }

    @Override
    public void logoutAllOtherDevices(Integer userId, String currentDeviceId) {

    }

    @Override
    public void deleteDevice(Integer userId, Long deviceId) {

    }

    @Override
    public void updateDeviceName(Integer userId, Long deviceId, String deviceName) {

    }

    @Override
    public void updateLastLoginTime(Integer userId, String deviceId) {

    }
}
